home *** CD-ROM | disk | FTP | other *** search
- // MatchLoop.cp
-
- #ifndef MatchLoop_h
- #include "MatchLoop.h"
- #endif
- #ifndef PatternMatcher_h
- #include "PatternMatcher.h"
- #endif
- #ifndef Overflow_h
- #include "Overflow.h"
- #endif
-
- bool MatchLoop::Matching() const
- {
- Assert( matchEnd > source.Start() );
- Assert( matchEnd <= source.End() );
- Assert( pattern->Target().End() > pattern->Target().Start() );
-
- const uint8 *sourcePosition = matchEnd;
- const uint8 *targetPosition = pattern->Target().End();
-
- if ( Asuint32( matchEnd - source.Start() ) < pattern->Length() )
- {
- do
- if ( *--sourcePosition != *--targetPosition )
- return false;
- while ( sourcePosition > source.Start() );
-
- Assert( matchedPrefix >= Asuint32( targetPosition - pattern->Target().Start() ) );
- sourcePosition = pattern->Target().Start() + matchedPrefix;
- }
-
- do
- if ( *--sourcePosition != *--targetPosition )
- return false;
- while ( targetPosition > pattern->Target().Start() );
-
- return true;
- }
-
- bool MatchLoop::PartiallyMatching() const
- {
- Assert( matchEnd > source.End() );
- Assert( matchEnd >= source.Start() + pattern->Length() );
- Assert( matchEnd <= source.End() + pattern->Length() );
-
- const uint8 *sourcePosition = matchEnd - pattern->Length();
- const uint8 *targetPosition = pattern->Target().Start();
-
- while ( sourcePosition < source.End()
- && targetPosition < pattern->Target().End() )
- if ( *sourcePosition++ != *targetPosition++ )
- return false;
-
- return true;
- }
-
- void MatchLoop::Advance()
- {
- Assert( matchEnd >= source.Start() + pattern->Target().Length() - matchedPrefix );
-
- for ( ; Unfinished(); matchEnd += pattern->Advance( matchEnd[-1] ) )
- if ( Matching() )
- return;
-
- uint32 targetLength = pattern->Target().Length();
- for ( const uint8 *p = source.End(); p > matchEnd - targetLength; p-- )
- {
- const uint8 *possibleEnd = p + pattern->Advance( p[-1] );
- if ( possibleEnd > matchEnd )
- matchEnd = possibleEnd;
- }
-
- while ( !PartiallyMatching() )
- matchEnd++;
-
- matchedPrefix = pattern->Length() - ( matchEnd - source.End() );
- }
-
- MatchLoop::MatchLoop( const PatternMatcher& thePattern )
- : pattern( &thePattern ),
- matchEnd( 0 ),
- matchedPrefix( 0 )
- {
- }
-
- MatchLoop::MatchLoop( const PatternMatcher& thePattern, ConstData firstSource )
- : pattern( &thePattern ),
- source( firstSource ),
- matchEnd( firstSource.Start() + pattern->Length() ),
- matchedPrefix( 0 )
- {
- Advance();
- }
-
- void MatchLoop::Start( ConstData theSource )
- {
- source = theSource;
- matchEnd = source.Start() + pattern->Length();
- Advance();
- }
-
- void MatchLoop::Continue( ConstData theSource )
- {
- source = theSource;
- matchEnd = source.Start() + pattern->Length() - matchedPrefix;
- Advance();
- }
-
- void MatchLoop::operator++()
- {
- matchEnd += pattern->Advance( matchEnd[-1] );
- Advance();
- }
-